package pong.game.objects;

import java.util.Vector;

import pong.mathematic.TempVector2D;
import pong.mathematic.Vector2D;
import pong.mathematic.Vector3D;

public class GL_ActiveItem extends GL_Object {

	private static int idCounter = 0;

	protected int id = 0;

	protected float rotationSpeed = 0f;
	protected float startRadius = 0f;
	protected float radius = 0.025f;
	protected final Vector3D direction = new Vector3D();
	protected final Vector3D collideImpulse = new Vector3D();

	private boolean isNeedSynchronize = true;

	private float drag = 0.9f;
	private float collideImpulseDrag = 1;
	private float bounce = 0.02f;
	private float bounceWall = 0.02f;

	private boolean showRadius = false;
	private final Vector<Vector2D> accelerations = new Vector<Vector2D>();

	public GL_ActiveItem(Vector3D center, float width, float height) {// , int
																		// visibleTime,
																		// float
																		// maxCurAlpha)
																		// {
		super(center, width, height);
		calcRadius();
		// radius = startRadius;
		this.id = idCounter++;

	}

	public boolean isIn(Vector3D clickPos) {
		return isIn(clickPos, 0);
	}

	public boolean isIn(Vector3D clickPos, float addDistance) {
		return center.distance(clickPos) <= radius + addDistance;
	}

	@Override
	public boolean isIn(Vector2D clickPos) {
		return isIn(clickPos, 0);
	}

	public boolean isIn(Vector2D clickPos, float addDistance) {
		return center.distance(clickPos) <= radius + addDistance;
	}

	// Physic Engine
	public Vector2D sumAccel() {
		if (accelerations.size() == 0)
			return null;

		Vector2D result = new Vector2D();
		for (int i = 0; i < accelerations.size(); i++) {
			result.add(accelerations.get(i));
		}
		accelerations.clear();
		return result;
	}

	public void addAccel(Vector2D vec) {
		this.accelerations.add(vec);
	}

	public void applyDrag(float drag) {
		direction.multy(drag);
	}

	public void applyCollideImpulseDrag(float drag) {
		collideImpulse.multy(drag);
	}

	public void moveEnts(float maxSpeed, float timeFraction) {
		if (direction.distance() * timeFraction > maxSpeed) {
			direction.normalize();
			direction.multy(maxSpeed / timeFraction);
		}

		setCenter(center.getX() + direction.getX() * timeFraction, center.getY() + direction.getY() * timeFraction,
				center.getZ() + direction.getZ() * timeFraction);
	}

	public void rotate(float timeFraction) {
		rotationAngle += rotationSpeed * timeFraction;
	}

	// public void scale(float timeFraction) {
	// scaleValue += scaleSpeed * timeFraction;
	// setRadius(startRadius * scaleValue);
	//
	// if (scaleValue > maxScale) {
	// scaleValue = maxScale;
	// scaleSpeed = 0f;
	// }
	// }

	@Override
	protected void initVertexesForNewSize(float width, float height) {
		super.initVertexesForNewSize(width, height);
		calcRadius();
	}

	public TempVector2D velVector() {
		return new TempVector2D(direction.getX(), direction.getY());
	}

	// GETers and SETers
	public Vector3D getDirection() {
		return direction;
	}

	public Vector3D getCollideImpulse() {
		return collideImpulse;
	}

	public float getRotationSpeed() {
		return rotationSpeed;
	}

	public void setRotationSpeed(float rotationSpeed) {
		this.rotationSpeed = rotationSpeed;
	}

	@Override
	public void setScaleValue(float scaleValue) {
		this.scaleValue = scaleValue;
		setRadius(startRadius * scaleValue);
	}

	// public float getScaleSpeed() {
	// return scaleSpeed;
	// }
	//
	// public void setScaleSpeed(float scaleSpeed) {
	// this.scaleSpeed = scaleSpeed;
	// }

	// public void setMaxScale(float maxScale) {
	// this.maxScale = maxScale;
	// }
	//
	// public float getMaxScale() {
	// return maxScale;
	// }

	public void setDirection(Vector2D newDir) {
		setDirection(newDir.getX(), newDir.getY());
	}

	public void setDirection(float x, float y) {
		direction.setX(x);
		direction.setY(y);
	}

	public void setCollideImpulse(Vector2D newImpulse) {
		setCollideImpulse(newImpulse.getX(), newImpulse.getY());
	}

	public void setCollideImpulse(float x, float y) {
		collideImpulse.setX(x);
		collideImpulse.setY(y);
	}

	public float getRadius() {
		return radius;
	}

	public void setRadius(float radius) {
		this.radius = radius;
	}

	public void calcRadius() {
		startRadius = Math.max(height, width) / 2;
		setRadius(startRadius);
	}

	public static int getIdCounter() {
		return idCounter;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public float getStartRadius() {
		return startRadius;
	}

	public void setStartRadius(float startRadius) {
		this.startRadius = startRadius;
	}

	public float getDrag() {
		return drag;
	}

	public void setDrag(float drag) {
		this.drag = drag;
	}

	public float getCollideImpulseDrag() {
		return collideImpulseDrag;
	}

	public void setCollideImpulseDrag(float drag) {
		this.collideImpulseDrag = drag;
	}

	public float getBounce() {
		return bounce;
	}

	public void setBounce(float bounce) {
		this.bounce = bounce;
	}

	public float getBounceWall() {
		return bounceWall;
	}

	public void setBounceWall(float bounceWall) {
		this.bounceWall = bounceWall;
	}

	public void setShowRadius() {
		this.showRadius = true;
	}

	public boolean isShowRadius() {
		return showRadius;
	}

	public boolean isNeedSynchronize() {
		return isNeedSynchronize;
	}

	public void setIsNeedSynchronize(boolean value) {
		isNeedSynchronize = value;
	}

}
